#! /usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020/3/14 21:08
# @Author : youngchaolin
# @File : 深浅copy.py

print()

'''
深浅copy
浅copy：嵌套的可变数据类型如list，dict，copy后指向的是同一个内存空间
深copy：嵌套的可变数据类型如list，dict，copy后指向的是不同的内存空间
'''

# 普通赋值
l1=[1,2,3]
l2=l1
# l1和l2的id一样
l2.append(4)
print(id(l1))
print(id(l2))
print(l1)
print(l2)

# 浅copy
l1=[1,2,3]
l2=l1.copy()
l1.append(4)
# 这里产生了两个id
# print(id(l1))
# print(id(l2))
# 查看元素的id，都一样
print(id(l1[0]))
print(id(l2[0]))
print(l1,id(l1)) # [1, 2, 3,4]
print(l2,id(l2)) # [1, 2, 3]
# l1和l2的id不一样，但是里面元素的id一样，说明l1和l2都指向内存中同一份内存地址

# 浅copy
l1=[1,2,3,['messi','ronald']]
l2=l1.copy()
l1[-1].append('herry')
# 列表里的每个元素，id一样
print(id(l1[-1]))
print(id(l2[-1]))
# 但是整体l1和l2的id不一样
# print(id(l1))
# print(id(l2))
print(l1,id(l1)) # [1, 2, 3, ['messi', 'ronald', 'herry']]
print(l2,id(l2)) # [1, 2, 3, ['messi', 'ronald', 'herry']]

# 同样，l1和l2也指向的内存地址一样，由于l1修改了可变数组，l2指向同一个可变数组，因此也修改了

# 浅copy
l1=[1,2,3,['messi','ronald']]
l2=l1.copy()
l1[0]=520
# 重新查看元素的id
print(id(l1[0]),id(l1[1]),id(l1[2]),id(l1[3]))
print(id(l2[0]),id(l2[1]),id(l2[2]),id(l2[3]))
print(l1,id(l1))
print(l2,id(l2))
# 由于l1[0]的元素是int，属于不可变数据类型，因此内存中会开辟一个新的地址，其他的元素还是共用的

# 深copy
import copy
l1=[1,2,3,['messi','ronald']]
l2=copy.deepcopy(l1)
# 给元素赋值
l1[-1].append('herry')
# 重新查看元素的id
print(id(l1[0]),id(l1[1]),id(l1[2]),id(l1[3]))
print(id(l2[0]),id(l2[1]),id(l2[2]),id(l2[3]))

print(l1)
print(l2)
# 可以看出，不可变数据类型是共用内存地址，而可变数据类型如数组list就是开辟一个新的内存空间

# 面试题 考察切片是深拷贝还是浅拷贝
l1=[1,2,3,['messi','ronald']]
l2=l1[:] # 全切片
l1[-1].append('herry')
print(id(l1[0]),id(l1[1]),id(l1[2]),id(l1[3]))
print(id(l2[0]),id(l2[1]),id(l2[2]),id(l2[3]))
# 打印结果可以看出是浅拷贝
print(l1)
print(l2)

